from apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutor
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore

from app.db.database import engine


class Scheduler:
    def __init__(self):
        jobstores = {
            'default': SQLAlchemyJobStore(engine=engine)
        }
        executors = {
            'default': ThreadPoolExecutor(20),
            'processpool': ProcessPoolExecutor(5)
        }
        job_defaults = {
            'coalesce': False,
            'max_instances': 3
        }

        # from apscheduler.schedulers.background import BackgroundScheduler
        # self.scheduler = BackgroundScheduler(jobstores=jobstores, executors=executors, job_defaults=job_defaults, timezone='UTC')

        from apscheduler.schedulers.asyncio import AsyncIOScheduler
        self.scheduler = AsyncIOScheduler(jobstores=jobstores, executors=executors, job_defaults=job_defaults, timezone='UTC')

    async def add_job(self, func, *args, **kwargs):
        return self.scheduler.add_job(func, *args, **kwargs)

    async def modify_job(self, job_id, jobstore=None, **changes):
        return self.scheduler.modify_job(job_id, jobstore, **changes)

    async def reschedule_job(self, job_id, jobstore=None, trigger=None, **trigger_args):
        return self.scheduler.reschedule_job(job_id, jobstore, trigger, **trigger_args)

    async def pause_job(self, job_id, jobstore=None):
        return self.scheduler.pause_job(job_id, jobstore)

    async def resume_job(self, job_id, jobstore=None):
        return self.scheduler.resume_job(job_id, jobstore)

    async def remove_job(self, job_id, jobstore=None):
        return self.scheduler.remove_job(job_id, jobstore)

    async def get_job(self, job_id):
        return self.scheduler.get_job(job_id)

    async def get_jobs(self, jobstore=None):
        return self.scheduler.get_jobs(jobstore)

    async def print_jobs(self, jobstore=None):
        return self.scheduler.print_jobs(jobstore)

    async def pause(self):
        return self.scheduler.pause()

    async def resume(self):
        return self.scheduler.resume()

    async def state(self):
        return self.scheduler.state()

    async def start(self, *args, **kwargs):
        return self.scheduler.start(*args, **kwargs)

    async def shutdown(self, *args, **kwargs):
        return self.scheduler.shutdown(*args, **kwargs)

scheduler = Scheduler()